//
//  Quotation.h
//  ChartRefactor
//
//  Created by CaoJun on 15/3/2.
//  Copyright (c) 2015年 CaoJun. All rights reserved.
//

#ifndef __ChartRefactor__Quotation__
#define __ChartRefactor__Quotation__

#include "EnumDefinition.h"
#include "Rectangle.h"
#include "DataOption.h"
#include "Observable.h"
#include "Observer.h"
#include "Metal.h"
#include "YTXObject.h"
#include "YTXTime.h"

#import <AFNetworking/AFHTTPSessionManager.h>

#include <string>
#include <vector>
#include <utility>
#include <queue>
#include <list>

namespace ytx{
    class Quotation;
}

@interface QuotationHttpBrige : NSObject  {
@private
    
}

@property (nonatomic, unsafe_unretained) ytx::Quotation * quotation;

@property (nonatomic, copy) NSString * tag;

- (void)GET:(NSString *)URLString
 parameters:(id)parameters acceptableContent:(NSString *)acceptableContent;

- (void)GET:(NSString *)URLString
 parameters:(id)parameters;

- (instancetype)initWithQuotation:(ytx::Quotation *)quotation
                          withTag:(NSString *)tag;
- (void)invalidate;
@end

namespace ytx{

    namespace UpDropStatus {
        enum UpDropStatus {
            Drop, Up, Balance
        };
    }
    
    struct LSPItem {
        std::string buyRatio;
        std::string sellRatio;
        std::string totalRatio;
        YTXTime dateTime;
    };
    
    struct KLineItem {
        std::string tradeDate; //20170403
        double open;
        double high;
        double low;
        double close;
        double volume;
        double value;
        double totalHold;// 持仓量
        YTXTime dateTime;
        double upDrop;//涨跌
        double percent;//涨跌幅
        double totalVolume;
        double totalValue;
        double IsCurrent;//为0表示不是本日/本周，为1表示是本日/本周
        bool status;
        double getClose() const {return close;};
        double getHigh() const {return high;};
        double getLow() const {return low;};
        double getOpen() const {return open;};
        
        bool const isEqual(KLineItem item) {
            return tradeDate == item.tradeDate && dateTime == item.dateTime && open == item.open && high == item.high && close == item.close && low == item.low;
        };
    };

    class Quotation : YTXObject
    {
    private:
        
    protected:
        TimeString originTimeString;
        ytx::Rect originRow;
        ytx::Rect originColumn;
        std::vector<std::vector<double> > lineTypeData;
        DataOption createOption(std::map<std::string, std::string> option, std::string routing);
        std::vector<std::string> task;
        
        void queue(std::string taskName);
        void dequeue();
        virtual void taskFactory(std::string taskName);
        
        std::map<std::string, std::queue<std::string> > behavior;
        std::map<std::string, QuotationHttpBrige*> requestbehavior;
        
        void registerBehavior(std::string eventName, std::string behaviorName);
        
        //excute once
        void executeBehavior(std::string eventName);
        
        virtual void behaviorFactory(std::string behaviorName);
        
        bool redrawFlag;
    public:
        virtual void firstFailRequestHandler(std::string tag);
        
        virtual void callback(std::string tag, std::string data);
        
        virtual void onFail(std::string tag);
        
        void onFailBehavior(std::string tag);
        void callbackBehavior(std::string tag, std::string data);
        
        virtual void requestData(const std::string tag, const DataOption & dataOption, const std::string acceptableContent="text/plain");
        
        //颜色 值
        virtual std::pair<std::string, std::string> getTopSideInfoText() const;
        virtual std::vector<std::pair<std::string, std::string> > getTopSideText(const std::vector<std::vector<double> > & data, int index) const;
        virtual std::vector<std::pair<std::string, std::string> > getTopSideText(int index) const;
        virtual std::vector<std::pair<std::string, std::string> > getTopSideText() const;
        virtual std::vector<std::pair<double, std::string> > getLeftSideText(int startIndex, int endIndex, const Rectangle & rect, const Style & style) const = 0;
        virtual const std::vector<std::string> & getBottomSideText(SizeType::SizeType) const;
        
        virtual UpDropStatus::UpDropStatus getUpDropStatus(int index);
        
        LineType::LineType quotationType;
        std::string marketType;
        int toFix;
        bool hasVolume;
        
        QuotationType::QuotationType type;
        YTXTime dateTo;
        YTXTime dateFrom;
        int drawingCount;
        std::string QuotationName;
        std::string id;
        
        YTXTime day;
        double prevValue;
        
        std::vector<std::string> timeString;
        ytx::Rect row;
        ytx::Rect column;
        
        virtual int getDataLength() const;
        
        std::vector<std::string> titleType;
        
        std::pair<std::string, std::string> infoTitle;
        
        std::string lineRemaind;
        
        std::string nickName;
        
        std::vector<std::vector<double> > indexData;// BYJZ     vector<double> type ；  GameMatrixType 类型
        
        std::vector<std::string> dateData;
        std::vector<std::string> dateRuler;// 一分钟时间标尺
        std::vector<std::vector<double> > lineData;// BYZJ Bound1， 参与计算 最大最小价格范围
        //vector<double> lineDataBound1;
        //vector<double> lineDataBound2;
        
        std::string currentDate;// 服务器当前交易日
        
        std::vector<std::pair<int,int> > lineDataDrawPartIndex;
        // 专门为了计算lineType而产生
        std::vector<KLineItem> kLineData;
        std::vector<LSPItem> lspData;
        virtual bool equal(const Quotation * other) const;
        
        virtual bool isRedrawAndClear();
        
        virtual bool hasCrosshairsYData() const;
        
        virtual bool hasData() const;
        virtual bool hasData(int index) const;
        virtual void cleanData();
        virtual void calculateIfHasData();
        
        Quotation(std::string id, std::string currrntDate, LineType::LineType quotationType, std::string marketType, bool hasVolume, int toFix);
        
        Quotation();
        
        virtual ~Quotation();
        
        std::pair<double, double> getLineDataMinMax(int startIndex, int endIndex) const;
        std::pair<double, double> getKLineDataMinMax(int startIndex, int endIndex) const;
        
        virtual std::pair<double, double> getDataMinMax(int startIndex, int endIndex) const;
        
        virtual std::pair<double, double> getAdjustedDataMinMax(int startIndex, int endIndex, const Rectangle & rect) const;
        
        LineType::LineType getQuotationType();
        
        bool isHasVolume();
        
        void setHasVolume(bool hasVolume);
        
        void setQuotationType(LineType::LineType quotationType);
        
        std::string getMarketType();
        
        void setMarketType(std::string marketType);
        
        int getToFix();
        
        void setToFix(int toFix);
        
        QuotationType::QuotationType getType();
        
        void setType(QuotationType::QuotationType);
        
        YTXTime getDateTo();
        
        void setDateTo(YTXTime dateTo);
        
        YTXTime getDateFrom();
        
        int fixIndexRange(int index) const;
        
        void setDateFrom(YTXTime dateFrom);
        
        int getDrawingCount();
        
        void setDrawingCount(int drawingCount);
        
        std::string getQuotationName();
        
        void setQuotationName(std::string quotationName);
        
        std::string getId();
        
        void setId(std::string id);
        
        YTXTime getDay();
        
        void setDay(YTXTime day);
        
        double getPrevValue();
        
        void setPrevValue(double prevValue);
        
        std::vector<std::string> & getTitleType();
        
        void setTitleType(std::vector<std::string> & titleType);
        
        std::string getNickName();
        
        void setNickName(std::string nickName);
        
        const std::vector<std::string> & getDateData();
        
        void setDateData(std::vector<std::string> & dateData);
        
        std::vector<std::vector<double> > & getLineData();
        
        void setLineData(std::vector<std::vector<double> > & lineData);
        
        std::vector<KLineItem> & getKLineData();
        
        void setKLineData(std::vector<KLineItem> & klineData);
        
        virtual std::string getCrosshairXData(int index);
        
        virtual std::string getCrosshairYData(int index) = 0;
        
        virtual double getCrosshairXValue(int index);
        
        std::vector<std::vector<double> > & getLineTypeData();
        
        void setLineTypeData(std::vector<std::vector<double> > & lineTypeData);
        
        std::vector<std::string> & getTimeString();
        
        void setTimeString(std::vector<std::string>  & timeString);
        
        ytx::Rect & getRow();
        
        void setRow(const ytx::Rect & row);
        
        ytx::Rect & getColumn();
        
        void setColumn(const ytx::Rect & column);
        
        const TimeString & getOriginTimeString() const;
        
        void setOriginTimeString (const TimeString & originTimeString);
        
        ytx::Rect & getOriginRow();
        
        void setOriginRow(ytx::Rect & originRow);
        
        ytx::Rect & getOriginColumn();
        
        void setOriginColumn(ytx::Rect & originColumn);
        
        std::string getLineRemaind();
        
        void setLineRemaind(std::string lineRemaind);
    };
}


#endif /* defined(__ChartRefactor__Quotation__) */
